#include"Contact.h"
#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>
#include<string.h>

struct Contact
{
    TCCP *a;
    int capacity;
    int size;
};

Con *InitCon(int capacity)
{
    Con *c=(Con *)malloc(sizeof(Con));
    if(c==NULL)
    {
        printf("InitCon malloc 申请失败\n");
        return NULL;
    }
    c->capacity= capacity;
    c->size=0;
    c->a=(TCCP *)malloc(sizeof(TCCP)*capacity);
    if(c->a==NULL)
    {
        printf("InitDec malloc array 申请失败\n");
        free(c);
        return NULL;
    }
    return c;
}

void AddContact(Con *c,TCCP telephone)
{
    if(c->size>=c->capacity)
    {
        c->capacity *= 2;
        TCCP *NewPtr=realloc(c->a,sizeof(TCCP)*c->capacity);
        if(NewPtr==NULL)
        {
            printf("扩容数组失败");
            c->capacity/=2;
            return;
        }
        c->a=NewPtr;
    }
    c->a[c->size]=telephone;
    c->size++;
}

void FastSort(TCCP *a, int start, int end, bool(*Compare)(TCCP, TCCP))
{
    if(start>=end)
    return;

    int left= start;
    int right= end;
    TCCP temp=a[left];
    while(left<right)
    {
        while(Compare(a[right],temp)&&left<right)
        {
            right--;
        }
        if(left<right)
        {
            a[left]=a[right];
            left++;
        }
        
        while (Compare(temp,a[left])&&left<right)
        {
            left++;
        }
        if(left<right)
        {
            a[right]=a[left];
            right--;
        }
    }
    a[left]=temp;
    FastSort(a,start,left-1,Compare);
    FastSort(a,right+1,end,Compare);
}

void Sort(Con *c,bool(*Compare)(TCCP, TCCP))
{
    FastSort(c->a,0,c->size-1,Compare);
}

Tel* BinarySearch(Con* Array, TCCP name,bool (*GreatName)(void *p1, void *p2),bool (*GreatName2)(void *p1, void *p2))
{
    int left=0;
    int right= Array->size-1;
    while(left<=right)
    {
        int mid= left+(right-left)/2;
        // int mid= (left & right) + ((left ^ right)>>1);
    
    if(GreatName(Array->a[mid],name))
        right= mid-1;

    else if(GreatName2(name,Array->a[mid]))
        left= mid+1;

    else
        return Array->a[mid];
    }
    return NULL;
}

Tel* Searchname(Con *Array, TCCP name)
{
    return BinarySearch(Array, name, GreatName,GreatName2);
}

Tel* SearchTel(Con *Array, void *data, bool (*IsEqual)(void *, void *))
{
    for(int i=0; i< Array->size;i++)
    {
        if(IsEqual(Array->a[i],data))
        {
            return Array->a[i];
        }
    }
    return NULL;
}

void RemoveByIndex(Con *Array, int index)
{
    if(index<0 || index >= Array->size)
    {
        printf("非法删除位置\n");
        return;
    }
    for(int i=index; i<Array->size; i++)
    {
        Array->a[i]= Array->a[i+1];
    }
    Array->size--;
}

void RemoveTel(Con *Array,void *data, bool (*IsEqual)(void *, void *))
{
    for(int i=0; i< Array->size; i++)
    {
        if(IsEqual(Array->a[i],data))
        {
            RemoveByIndex(Array,i);            
            i--;
        }
    }
    printf("删除成功\n");
}

void FreeCon(Con *c,void (*Free)(TCCP))
{
    if(Free)
    {
        for(int i=0; i<c->size; i++)
        {
            Free(c->a[i]);
        }   
    }
    free(c->a);
    free(c);
}

void PrintCon(Con *c,void (*Print)(TCCP))
{
    printf("size:%d    capacity:%d\n",c->size,c->capacity);
    for(int i=0; i<c->size; i++)
    {
        Print(c->a[i]);
    }
    printf("\n");
}

